package org.grow.leave.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.grow.leave.dao.LeaveBillMapper;
import org.grow.leave.entity.*;
import org.grow.leave.entity.enums.ApplyState;
import org.grow.leave.entity.enums.AuditState;
import org.grow.leave.exception.LeaveException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * @Author: xwg
 * @CreateDate: 2021/10/19
 */
@RestController
@RequestMapping("/leave/leaveBill")
public class LeaveBillController {

    @Autowired
    private LeaveBillMapper leaveBillMapper;

    @PostMapping("/insert")
    public LeaveBill insert(@RequestBody LeaveBill leaveBill) {
//        leaveBill
//        前端决定的数据 需要校验 如果校验失败 抛出异常，配合统一异常处理 给前端一个回复
        LocalDateTime startTime = leaveBill.getStartTime();
        LocalDateTime endTime = leaveBill.getEndTime();
        if (!startTime.isBefore(endTime)) {
            throw new LeaveException("开始时间必须在结束时间之前");
        }
        leaveBill.setAuditWord(null);

//        后端决定的数据
        leaveBill.setLeaveId(0);
        leaveBill.setDeleted(false);
        leaveBill.setVersion(0);
//        申请人相关
        leaveBill.setApplier(SecurityContextHolder.getContext().getAuthentication().getName());
        leaveBill.setApplyTime(LocalDateTime.now());
        leaveBill.setApplyState(ApplyState.saved);
//        审核人相关
        leaveBill.setAuditor(null);
        leaveBill.setAuditTime(null);
        leaveBill.setAuditState(AuditState.notAudit);

        System.out.println(leaveBill);
        leaveBillMapper.insert(leaveBill);
        return leaveBill;
    }

    @PostMapping("/query/apply")
    public PageResults<LeaveBill> queryApply(
            @RequestBody ApplySearchForm applySearchForm) {
        ApplyQueryCondition qc = applySearchForm.getQueryCondition();
        Integer pageSize = applySearchForm.getPageSize();
        Integer pageNum = applySearchForm.getPageNum();
        if (pageNum <= 0) {
            throw new LeaveException("查询页数不行小于等于0");
        }

        IPage<LeaveBill> page = new Page<>(pageNum, pageSize);
        String applier = SecurityContextHolder.getContext().getAuthentication().getName();
        IPage<LeaveBill> billIPage = leaveBillMapper.dynamicQueryApply(page, qc, applier);

        return new PageResults<LeaveBill>(billIPage.getTotal(), billIPage.getRecords());

    }

    @GetMapping("/find/apply/{leaveId}")
    public LeaveBill findApply(@PathVariable("leaveId") Integer leaveId) {

        LeaveBill leaveBill = leaveBillMapper.selectById(leaveId);
        String currentUser = SecurityContextHolder.getContext().getAuthentication().getName();
        if (leaveBill == null) {
            throw new LeaveException("查无此单");
        }
        if (!leaveBill.getApplier().equals(currentUser)) {
            throw new LeaveException("当前登录人" + currentUser + "不能查看其他人信息:" + leaveBill.getApplier());
        }
        return leaveBill;
    }

    @PutMapping("/modify")
    public LeaveBill modify(@RequestBody LeaveBill leaveBill) {

        LeaveBill leaveBillFromDb = leaveBillMapper.selectById(leaveBill.getLeaveId());
        leaveBillFromDb.setStartTime(leaveBill.getStartTime());
        leaveBillFromDb.setEndTime(leaveBill.getEndTime());
        leaveBillFromDb.setReason(leaveBill.getReason());
        leaveBillFromDb.setLeaveType(leaveBill.getLeaveType());

        if (!leaveBillFromDb.getApplyState().equals(ApplyState.saved)) {
            throw new LeaveException("单据只有处于未提交未审核状态才能被编辑");
        }
        if (!leaveBillFromDb.getAuditState().equals(AuditState.notAudit)) {
            throw new LeaveException("单据只有处于未提交未审核状态才能被编辑");
        }


        leaveBillFromDb.setApplyState(ApplyState.saved);
        leaveBillFromDb.setAuditState(AuditState.notAudit);


        leaveBillMapper.updateById(leaveBillFromDb);
        return leaveBillFromDb;
    }

    @PutMapping("/submit/{leaveId}")
    public Boolean submit(@PathVariable("leaveId") Integer leaveId) {
        LeaveBill leaveBill = leaveBillMapper.selectById(leaveId);
//        A -> B
//        1确定你处于A状态  2拿到相关事件信息 3设置状态转变 4状态转变后的操作
        if (!leaveBill.getApplyState().equals(ApplyState.saved)) {
            throw new LeaveException("单据只有处于未提交未审核状态才能被提交");
        }
        if (!leaveBill.getAuditState().equals(AuditState.notAudit)) {
            throw new LeaveException("单据只有处于未提交未审核状态才能被提交");
        }
//        状态机思维来看
        leaveBill.setApplyState(ApplyState.submitted);
        leaveBill.setAuditState(AuditState.notAudit);

        leaveBill.setApplyTime(LocalDateTime.now());
        int i = leaveBillMapper.updateById(leaveBill);
        return i == 1;
    }

    @PostMapping("/query/audit")
    public PageResults<LeaveBill> queryAudit(
            @RequestBody AuditSearchForm auditSearchForm) {

        AuditQueryCondition qc = auditSearchForm.getQueryCondition();
        Integer pageNum = auditSearchForm.getPageNum();
        Integer pageSize = auditSearchForm.getPageSize();
        IPage<LeaveBill> page = new Page<>(pageNum, pageSize);

        IPage<LeaveBill> r = leaveBillMapper.dynamicQueryAudit(page, qc, ApplyState.submitted);

        return new PageResults<>(r.getTotal(), r.getRecords());
    }

    @GetMapping("/find/audit/{leaveId}")
    public LeaveBill findAudit(@PathVariable Integer leaveId) {
        LeaveBill leaveBill = leaveBillMapper.selectById(leaveId);
        if (leaveBill == null) {
            throw new LeaveException("查无此单");
        }
        if (leaveBill.getApplyState() != ApplyState.submitted) {
            throw new LeaveException("审核页面只能查看已提交的请假条");
        }
        return leaveBill;
    }

    //    审核通过 审核不通过
    @PutMapping("/auditSucceeded")
    public Boolean auditSucceeded(@RequestBody LeaveBill leaveBill) {
//        事件信息

        LeaveBill leaveBillFromDb = leaveBillMapper.selectById(leaveBill.getLeaveId());
        leaveBillFromDb.setAuditor(SecurityContextHolder.getContext().getAuthentication().getName());
        leaveBillFromDb.setAuditWord(leaveBill.getAuditWord());
//        确定处于A状态 只有 已提交 未审核 状态才可以审核通过
        if (!leaveBillFromDb.getApplyState().equals(ApplyState.submitted)) {
            throw new LeaveException("单据只有处于已提交未审核状态才能被审核通过");
        }
        if (!leaveBillFromDb.getAuditState().equals(AuditState.notAudit)) {
            throw new LeaveException("单据只有处于已提交未审核状态才能被审核通过");
        }

//        转为B状态
        leaveBillFromDb.setApplyState(ApplyState.submitted);
        leaveBillFromDb.setAuditState(AuditState.auditSucceeded);

//       善后操作
        leaveBillFromDb.setAuditTime(LocalDateTime.now());
        int i = leaveBillMapper.updateById(leaveBillFromDb);
        return i == 1;

    }

    @PutMapping("/auditFailed")
    public Boolean auditFailed(@RequestBody LeaveBill leaveBill) {

        leaveBill.setAuditor(SecurityContextHolder.getContext().getAuthentication().getName());
//        处于A状态  只有处于已提交 未审核状态的才能提交
        if (!leaveBill.getApplyState().equals(ApplyState.submitted)) {
            throw new LeaveException("单据只有处于已提交未审核状态才能被审核不通过");
        }
        if (!leaveBill.getAuditState().equals(AuditState.notAudit)) {
            throw new LeaveException("单据只有处于已提交未审核状态才能被审核不通过");
        }

        leaveBill.setApplyState(ApplyState.submitted);
        leaveBill.setAuditState(AuditState.auditFailed);


        leaveBill.setAuditTime(LocalDateTime.now());
        int i = leaveBillMapper.updateById(leaveBill);
        return i == 1;

    }

    @PutMapping("/confirm/{leaveId}")
    public Boolean confirm(@PathVariable Integer leaveId) {

        LeaveBill leaveBill = leaveBillMapper.selectById(leaveId);
//        判断是否为空 抛出异常； 判断该单是否是登录用户的请假单 抛出异常；
//        以上两处省略了
        if (leaveBill.getApplyState() != ApplyState.submitted) {
            throw new LeaveException("单据只有处于已提交已审核状态才能被确认");
        }
        Boolean r = false;
        if (leaveBill.getAuditState() == AuditState.auditSucceeded) {
            r = true;
        }
        if (leaveBill.getAuditState() == AuditState.auditFailed) {
            r = true;
        }
        if (!r) {
            throw new LeaveException("单据只有处于已提交已审核状态才能被确认");
        }

//        状态转变
        leaveBill.setApplyState(ApplyState.ended);
        /**
         此时处于可能的两种状态，审核通过或审核不通过；
         */
//        leaveBill.setAuditState(AuditState);

        int i = leaveBillMapper.updateById(leaveBill);
        return i == 1;

    }

}
